﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Windows.Forms;
namespace CommonClasses.Utility
{
    /// <summary>
    /// Виды локализации путей
    /// </summary>
    public enum Locality
    {
        /// <summary>
        /// Локазизовать до exe-файла программы
        /// </summary>
        ExeFile, 
        /// <summary>
        /// Локализоваться относительно директории текущего проекта (для этого должна была быть вызвана SetCurrentProjectPath)
        /// </summary>
        CurrentProjectDir
    }

    /// <summary>
    /// Инструменты для работы с путями
    /// </summary>
    public static class PathUtility
    {
        /// <summary>
        /// Путь до текущего проекта
        /// </summary>
        private static string currentProjectDirPath = null;

        /// <summary>
        /// Путь до текущего проекта
        /// </summary>
        private static string CurrentProjectDirPath
        {
            get
            {
                if (currentProjectDirPath == null)
                    throw new Exception("Директория для проекта не установлена");
                return currentProjectDirPath;
            }
            set
            {
                currentProjectDirPath = value;
            }
        }

        /// <summary>
        /// Установлена ли директория для текущего проекта
        /// </summary>
        /// <returns></returns>
        public static bool IsCurrentProjectPathSet()
        {
            return currentProjectDirPath != null;
        }

        /// <summary>
        /// Установить директорию для текущего проекта
        /// </summary>
        /// <param name="currentProjectDirPath"></param>
        public static void SetCurrentProjectPath(string currentProjectDirPath)
        {
            CurrentProjectDirPath = currentProjectDirPath == null ? null : Path.GetFullPath(currentProjectDirPath);
        }

        /// <summary>
        /// Восстановить нужную текущую директорию 
        /// </summary>
        public static void RestoreCurrentDirectory(Locality locality)
        {
            switch (locality)
            {
                case Locality.ExeFile:
                    Environment.CurrentDirectory = Path.GetDirectoryName(Application.ExecutablePath);
                    break;
                case Locality.CurrentProjectDir:
                    Environment.CurrentDirectory = CurrentProjectDirPath;
                    break;
            }
        }

        /// <summary>
        /// Если путь глобальный, то сделать его относительным, если путь ведет к той же папке или глубже,
        /// по отношению к которой происходит локализация
        /// </summary>
        /// <param name="SomePath">путь</param>
        /// <returns>локальный путь, если его можно сделать относительным</returns>
        public static string MakePathLocal(string SomePath, Locality locality)
        {
            string pathRelativeTo = null;

            switch (locality)
            {
                case Locality.ExeFile:
                    pathRelativeTo = Path.GetDirectoryName(Application.ExecutablePath);
                    break;
                case Locality.CurrentProjectDir:
                    pathRelativeTo = CurrentProjectDirPath;
                    break;
            }

            // если нет корня, то путь начинается с .\
            if (!Path.IsPathRooted(SomePath))
                return (SomePath.StartsWith(".\\") ? SomePath : (SomePath.EndsWith(".") ? SomePath + "\\": ".\\" + SomePath));
            else
                //если не может быть относительым exe, то возвратим эту это строку
                if (!SomePath.StartsWith(pathRelativeTo))
                    return SomePath;
                //иначе удалим глобальность
                else
                {
                    SomePath = SomePath.Remove(0, pathRelativeTo.Length);
                    return SomePath.StartsWith("\\") ? "." + SomePath : ".\\" + SomePath; 
                }
        }


        /// <summary>
        /// Поменять в пути до файла имя файла, не изменяя самого пути и расширения
        /// </summary>
        /// <param name="newName">новое имя</param>
        /// <param name="oldPath">путь</param>
        /// <returns>новый путь</returns>c
        public static string ChangeFileName(string oldPath, string newName)
        {
            //return Path.GetDirectoryName(oldPath) + ((Path.GetDirectoryName(oldPath).Length < 2) ? "\\" : "") + newName +( (Path.GetExtension(oldPath) == "") ? "" : "\\") + Path.GetExtension(oldPath);
            if (Path.IsPathRooted(oldPath))
                return Path.GetDirectoryName(oldPath) + newName + ((Path.GetExtension(oldPath) == "") ? "" : ".") + Path.GetExtension(oldPath);
            else
            {
                if (!oldPath.StartsWith(".\\"))
                    oldPath.Insert(0, ".\\");
                return Path.GetDirectoryName(oldPath) + "\\" + newName + ((Path.GetExtension(oldPath) == "") ? "" : ".") + Path.GetExtension(oldPath);
            }
        }

        /// <summary>
        /// Вернуть путь до файла без расширения
        /// </summary>
        /// <param name="path">путь до файла</param>
        /// <returns></returns>
        public static string GetPathWithoutExtension(string path)
        {
            return Path.GetDirectoryName(path) + (Path.GetDirectoryName(path) != "" ? "\\" : "") + Path.GetFileNameWithoutExtension(path);
        }
    }
}
